// Package controller used to call driver interface to read or write device
package controller

import (
	"gitee.com/wangqiOvO/mapper-go-sdk/internal/common"
	"gitee.com/wangqiOvO/mapper-go-sdk/internal/configmap"
	"gitee.com/wangqiOvO/mapper-go-sdk/internal/di"
	"gitee.com/wangqiOvO/mapper-go-sdk/pkg/models"
	"k8s.io/klog/v2"
	"sync"
)

// SetVisitor write device in thread safe mode
func SetVisitor(instanceID string,twin configmap.Twin,drivers models.ProtocolDriver,mutex *sync.Mutex,dic *di.Container) error{
	mutex.Lock()
	defer mutex.Unlock()
	dic.Get(common.DriverPrefix+instanceID+twin.PropertyName)
	if twin.PVisitor.PProperty.AccessMode == "ReadOnly"{
		klog.V(4).Info(instanceID+":"+twin.PropertyName+" is ReadOnly")
		return nil
	}
	value, err := common.Convert(twin.PVisitor.PProperty.DataType,twin.Desired.Value)
	if err != nil {
		klog.V(4).Info("common.Convert error",err.Error())
		klog.Error(err)
		return err
	}
	err = drivers.WriteDeviceData(value)
	if err != nil {
		klog.V(4).Info("WriteDeviceData error",err.Error())
		klog.Error(err)
		return err
	}
	return nil
}

// GetDeviceData red device data in thread safe mode
func GetDeviceData(instanceID string,twin configmap.Twin,drivers models.ProtocolDriver,mutex *sync.Mutex,dic *di.Container) (string,error){
	mutex.Lock()
	defer mutex.Unlock()
	dic.Get(common.DriverPrefix+instanceID+twin.PropertyName)
	data,err := drivers.ReadDeviceData()
	if err != nil{
		return "",err
	}
	sData, err := common.ConvertToString(data)
	if err != nil {
		return "", err
	}
	klog.V(4).Infof("%s:%s value is %s",instanceID,twin.PropertyName,sData)
	return sData,nil
}

// GetDeviceStatus red device status in thread safe mode
func GetDeviceStatus(instanceID string,twin configmap.Twin,drivers models.ProtocolDriver,mutex *sync.Mutex,dic *di.Container) string {
	mutex.Lock()
	defer mutex.Unlock()
	dic.Get(common.DriverPrefix+instanceID+twin.PropertyName)
	status := drivers.GetDeviceStatus()
	if status{
		return common.DEVSTOK
	}
	return common.DEVSTDISCONN
}
